﻿/* Copyright (c) 2010 EPiServer AB
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
 * documentation files (the "Software"), to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
 * to permit persons to whom the Software is furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
 * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
using System.Text.RegularExpressions;
using System.Web;
using System.Web.Hosting;
using System.Web.UI;
using System.Web.UI.WebControls;
using EPiServer.Core;
using EPiServer.SpecializedProperties;
using EPiServer.Web;

namespace EPiServer.Municipality.Web.UI.WebControls {
    /// <summary>
    /// Summary description for LinkList.
    /// </summary>
    /// <remarks>
    /// </remarks>
    public class LinkList : WebControl, INamingContainer {
        /* *******************************************************************
         *  Properties 
         * *******************************************************************/
        #region public int Count
        /// <summary>
        /// Gets the Count of the LinkList
        /// </summary>
        /// <value></value>
        public int Count {
            get {
                return _count;
            }
        }
        private int _count;
        #endregion
        #region public string PropertyName
        /// <summary>
        /// Get/Sets the PropertyName of the LinkList
        /// </summary>
        /// <value></value>
        public string PropertyName {
            get { return ViewState["PropertyName"] as string; }
            set { ViewState["PropertyName"] = value; }
        }
        #endregion
        #region public LinkItemCollection LinkItems
        /// <summary>
        /// Get/Sets the LinkItemCollection of the LinkList
        /// </summary>
        /// <value></value>
        public LinkItemCollection LinkItems { get; set; }
        #endregion
        #region public PageData CurrentPage
        /// <summary>
        /// Gets the CurrentPage of the LinkList
        /// </summary>
        /// <value></value>
        public PageData CurrentPage {
            get {
                var pageBase = HttpContext.Current.Handler as PageBase;
                if (pageBase != null)
                    return pageBase.CurrentPage;
                return null;
            }
        }
        #endregion
        #region public ITemplate HeaderTemplate
        /// <summary>
        /// Get/Sets the ItemTemplate of the LinkList
        /// </summary>
        /// <value></value>
        [TemplateContainer(typeof(LinkTemplateContainer))]
        public ITemplate HeaderTemplate { get; set; }
        #endregion
        #region public ITemplate ItemTemplate
        /// <summary>
        /// Get/Sets the ItemTemplate of the LinkList
        /// </summary>
        /// <value></value>
        [TemplateContainer(typeof(LinkTemplateContainer))]
        public ITemplate ItemTemplate { get; set; }
        #endregion
        #region public ITemplate ExternalItemTemplate
        /// <summary>
        /// Get/Sets the ExternalItemTemplate of the LinkList
        /// </summary>
        /// <value></value>
        [TemplateContainer(typeof(LinkTemplateContainer))]
        public ITemplate ExternalItemTemplate { get; set; }
        #endregion
        #region public ITemplate FileItemTemplate
        /// <summary>
        /// Get/Sets the FileItemTemplate of the LinkList
        /// </summary>
        /// <value></value>
        [TemplateContainer(typeof(LinkTemplateContainer))]
        public ITemplate FileItemTemplate { get; set; }
        #endregion
        #region public ITemplate EmailItemTemplate
        /// <summary>
        /// Get/Sets the EmailItemTemplate of the LinkList
        /// </summary>
        /// <value></value>
        [TemplateContainer(typeof(LinkTemplateContainer))]
        public ITemplate EmailItemTemplate { get; set; }
        #endregion
        #region public ITemplate PageDataTemplate
        /// <summary>
        /// Get/Sets the PageDataTemplate of the LinkList
        /// </summary>
        /// <value></value>
        [TemplateContainer(typeof(LinkTemplateContainer))]
        public ITemplate PageDataTemplate { get; set; }
        #endregion
        #region public ITemplate FooterTemplate
        /// <summary>
        /// Get/Sets the ItemTemplate of the LinkList
        /// </summary>
        /// <value></value>
        [TemplateContainer(typeof(LinkTemplateContainer))]
        public ITemplate FooterTemplate { get; set; }
        #endregion
        /* *******************************************************************
         *  Methods 
         * *******************************************************************/
        #region protected override void CreateChildControls()
        /// <summary>
        /// 
        /// </summary>
        protected override void CreateChildControls() {
            Controls.Clear();
            var propertyLinkCollection = CurrentPage.Property[PropertyName] as PropertyLinkCollection;
            LinkItemCollection links = null;
            if (propertyLinkCollection != null && propertyLinkCollection.Links.Count > 0)
                links = propertyLinkCollection.Links;
            else if (LinkItems != null && LinkItems.Count > 0)
                links = LinkItems;

            if (links == null)
                return;

            _count = links.Count;

            if (HeaderTemplate != null) {
                var linkTemplateContainer = new LinkTemplateContainer(null);
                HeaderTemplate.InstantiateIn(linkTemplateContainer);
                Controls.Add(linkTemplateContainer);
            }
            for (int i = 0; i < links.Count; i++) {
                var linkTemplateContainer = new LinkTemplateContainer(links[i]);
                if (FileItemTemplate != null && IsFile(links[i].Href)) {
                    FileItemTemplate.InstantiateIn(linkTemplateContainer);
                    Controls.Add(linkTemplateContainer);
                } else if (ExternalItemTemplate != null && IsExternalLink(links[i].Href)) {
                    ExternalItemTemplate.InstantiateIn(linkTemplateContainer);
                    Controls.Add(linkTemplateContainer);
                } else if (EmailItemTemplate != null && IsEmailAdress(links[i].Href)) {
                    EmailItemTemplate.InstantiateIn(linkTemplateContainer);
                    Controls.Add(linkTemplateContainer);
                } else if (PageDataTemplate != null && IsPageData(links[i].Href)) {
                    PageDataTemplate.InstantiateIn(linkTemplateContainer);
                    Controls.Add(linkTemplateContainer);
                } else {
                    ItemTemplate.InstantiateIn(linkTemplateContainer);
                    Controls.Add(linkTemplateContainer);
                }
            }
            if (FooterTemplate != null) {
                var linkTemplateContainer = new LinkTemplateContainer(null);
                FooterTemplate.InstantiateIn(linkTemplateContainer);
                Controls.Add(linkTemplateContainer);
            }
        }
        #endregion
        #region public override void RenderBeginTag(HtmlTextWriter writer)
        /// <summary>
        /// 
        /// </summary>
        /// <param name="writer"></param>
        public override void RenderBeginTag(HtmlTextWriter writer) { }
        #endregion
        #region public override void RenderEndTag(HtmlTextWriter writer)
        /// <summary>
        /// 
        /// </summary>
        /// <param name="writer"></param>
        public override void RenderEndTag(HtmlTextWriter writer) { }
        #endregion
        #region private bool IsFile(string url)
        /// <summary>
        /// 
        /// </summary>
        /// <param name="url"></param>
        /// <returns>True if it is file, otherwise false.</returns>
        private bool IsFile(string url) {
            try {
                return HostingEnvironment.VirtualPathProvider.FileExists(url);
            } catch {
                return false;
            }
        }
        #endregion
        #region private bool IsExternalLink(string url)
        /// <summary>
        /// 
        /// </summary>
        /// <param name="url"></param>
        /// <returns>True if url is external link, otherwise false.</returns>
        private bool IsExternalLink(string url) {
            return url.ToLower().IndexOf("://") > -1;
        }
        #endregion
        #region private bool IsEmailAdress(string url)
        /// <summary>
        /// 
        /// </summary>
        /// <param name="url"></param>
        /// <returns>True if url is emailadress, otherwise false.</returns>
        private bool IsEmailAdress(string url) {
            const string pattern = @"\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*";
            var regex = new Regex(pattern);
            return regex.IsMatch(url);
        }
        #endregion
        #region private bool IsPageData (string url)
        /// <summary>
        /// 
        /// </summary>
        /// <param name="url"></param>
        /// <returns>True if url is page data, otherwise false.</returns>
        private bool IsPageData(string url) {
            string mappedUrl;
            if (!PermanentLinkMapStore.TryToMapped(url, out mappedUrl))
                return false;
            PageReference pageRef = PageReference.ParseUrl(mappedUrl);
            return !PageReference.IsNullOrEmpty(pageRef);
        }
        #endregion
        /* *******************************************************************
         *  Event methods 
         * *******************************************************************/
        #region protected override void OnDataBinding(System.EventArgs e)
        /// <summary>
        /// 
        /// </summary>
        /// <param name="e"></param>
        protected override void OnDataBinding(System.EventArgs e) {
            EnsureChildControls();
            base.OnDataBinding(e);
        }
        #endregion
    }
}